﻿using Blm.PgsqlDriver.Helpers;
using Blm.Utils.Extensions;
using Blm.Utils.Utility;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using VisionCloud.Core.Model.Enums;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Repository.Implement.Ms;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Service.Applet;
using VisionCloud.Service.Ms;
using VisionCloud.Utility;
using VisionCloud.Utility.Helpers;

namespace VisionCloud.Web
{
    public enum TaskUpdateType
    {
        /// <summary>
        /// 需要删除上版本数据
        /// </summary>
        NeedToDeleteLastVersionData = 1,

        /// <summary>
        /// 是新数据需要新增
        /// </summary>
        NewDataNeedToAdd = 2,

        /// <summary>
        /// 是旧版本数据，要修改，不需要显示。
        /// </summary>
        oldVersionDataNoShow = 3,

        /// <summary>
        /// 需要更新数据
        /// </summary>
        NeedToUpdate = 4
    }

    /// <summary>
    /// 定时（1秒）检查上传目录是否有文件，有则解压到指定目录
    /// </summary>
    public partial class UnzipTaskDataService : BackgroundService
    {
        private readonly MsReportService msReportService;
        private readonly TaskDataUploadService taskDataUploadService;
        private readonly ApartmentReportService apartmentReportService;
        private readonly IMsFileStatusRepository msFileStatusRepository;

        public UnzipTaskDataService(
            MsReportService msReportService,
            TaskDataUploadService taskDataUploadService,
            ApartmentReportService apartmentReportService,
            IMsFileStatusRepository msFileStatusRepository)
        {
            this.msReportService = msReportService;
            this.taskDataUploadService = taskDataUploadService;
            this.apartmentReportService = apartmentReportService;
            this.msFileStatusRepository = msFileStatusRepository;
        }

        private static readonly string taskData = ConfigHelper.GetValue<string>("TaskData");
        private static readonly string taskReportData = ConfigHelper.GetValue<string>("TaskReportData");
        private static readonly string taskDataBackup = ConfigHelper.GetValue<string>("TaskDataBackup");

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    Dowork();
                }
                catch
                {
                    // 注：定时服务不记录日志
                }
                finally
                {
                    await Task.Delay(5000);
                }
            }
        }

        public int WeekOfYear(DateTime dt, CultureInfo ci)
        {
            //强制设置周一是每周的第一天
            return ci.Calendar.GetWeekOfYear(dt, ci.DateTimeFormat.CalendarWeekRule, DayOfWeek.Monday);
        }

        /// <summary>
        /// 工作内容
        /// </summary>
        private async void Dowork()
        {
            List<FileInfo> needToHandleFile_OldVersion = UnzipTaskDataFileSystemMananger.GetNeedToHandleFile_OldVersion(taskData);
            List<FileInfo> needToHandleFile_NewVersion = UnzipTaskDataFileSystemMananger.GetNeedToHandleFile_NewVersion(taskData);
            List<UnzipTaskDataEntity> UnzipTaskDataEntityList = new List<UnzipTaskDataEntity>();
            needToHandleFile_OldVersion.ForEach(i =>
            {
                var result = UnzipTaskDataEntity.OldObjectByNewVersion(i, taskReportData, taskDataBackup);
                if (!result.IsHaveError)
                {
                    // 文件格式正确存到列表
                    UnzipTaskDataEntityList.Add(result);
                }
                else
                {
                    // 问题文件移动到error文件夹中
                    UnzipTaskDataFileSystemMananger.ErrorBuckUp(taskData, i.FullName);
                }
            });
            needToHandleFile_NewVersion.ForEach(i =>
            {
                var result = UnzipTaskDataEntity.NewObjectByNewVersion(i, taskReportData, taskDataBackup);
                if (!result.IsHaveError)
                {
                    UnzipTaskDataEntityList.Add(result);
                }
                else
                {
                    UnzipTaskDataFileSystemMananger.ErrorBuckUp(taskData, i.FullName);
                }
            });
            // 如果没有文件需处理直接跳出逻辑
            if (needToHandleFile_NewVersion.Count() <= 0 && needToHandleFile_OldVersion.Count() <= 0)
            {
                return;
            }
            var helper = new PostgreHelper();
            UnzipTaskDataEntityList = UnzipTaskDataEntityList.OrderBy(p => p.SrcFileInfo.CreationTime).ToList(); //needToHandleFile_OldVersion = needToHandleFile_OldVersion.OrderBy(p => p.CreationTime).ToList();

            await msFileStatusRepository.UpdateFileStatusAsync(UnzipTaskDataEntityList, FileStatusEnum.待处理);
            foreach (var unzipTaskDataEntity in UnzipTaskDataEntityList)
            {
                var fileInfo = unzipTaskDataEntity.SrcFileInfo;
                string taskIdIndt = string.Empty;
                try
                {
                    apartmentReportService.DeleteReportCache(unzipTaskDataEntity.TaskId.ToGuid());
                    msReportService.DeleteCompressReport(unzipTaskDataEntity.TaskId.ToGuid());

                    var file = fileInfo.FullName;
                    var HandleDirectoryResult = UnzipTaskDataFileSystemMananger.DirectoryHandle(unzipTaskDataEntity, taskReportData, taskData, taskDataBackup);
                    if (unzipTaskDataEntity.IsHaveError)
                        continue;

                    #region 基础数据导入云端的数据库

                    var dir = HandleDirectoryResult;//只有一个项目名称的文件夹
                    if (dir != null && dir.Length > 0)
                    {
                        string xmlPath = Path.Combine(dir[0], "基础数据", "dataset.xml");
                        using DataSet ds = new DataSet();
                        using StreamReader sr = new StreamReader(xmlPath, Encoding.Default);
                        using XmlReader rdr = XmlReader.Create(sr);
                        ds.ReadXml(rdr);
                        taskDataUploadService.UploadTableFromDataset(ds, unzipTaskDataEntity.UsbKeyNO, unzipTaskDataEntity.DestDirPath);
                    }

                    #endregion 基础数据导入云端的数据库

                    // 记录上传文件数量和大小
                    //Logger.Info($"结束处理文件:{file};文件大小:{file.Length / 1048576.0}MB");

                    await msFileStatusRepository.UpdateFileStatusAsync(unzipTaskDataEntity, FileStatusEnum.已处理);
                }
                catch (Exception e)
                {
                    Logger.Error($"数据上传失败, 文件名：{unzipTaskDataEntity.SrcFileInfo.Name}, 详细信息：{e.Message}", e);
                    await msFileStatusRepository.UpdateFileStatusAsync(unzipTaskDataEntity, FileStatusEnum.处理失败);
                    if (!string.IsNullOrEmpty(taskIdIndt))
                    {
                        var deleteSql = $"delete from \"MsTask\" where \"TaskId\" = '{taskIdIndt}';";
                        deleteSql += $"delete from \"CSMSTask\" where \"TaskId\" = '{taskIdIndt}';";
                        deleteSql += $"delete from \"MsSQualityAnalysis\" where \"TaskId\" = '{taskIdIndt}';";
                        deleteSql += $"delete from \"MsSPersonnelEfficiency\" where \"TaskId\" = '{taskIdIndt}';";
                        PgSqlHelper.ExecuteNonQuery(CommandType.Text, deleteSql);
                    }
                }
            }

            CopyHouseMapImageAndRedraw(UnzipTaskDataEntityList);
        }

        /// <summary>
        /// 复制热力图基础数据并且重新绘图
        /// </summary>
        /// <param name="unzipTasks"></param>
        public static void CopyHouseMapImageAndRedraw(List<UnzipTaskDataEntity> unzipTasks)
        {
            if (unzipTasks == null || unzipTasks.Count == 0)
                return;

            List<string> msPicDicList = new List<string>();

            //需要重新覆盖的目录列表
            List<(string sourceDir, string destDir)> copyDirList = new List<(string sourceDir, string destDir)>();

            //复制文件夹
            foreach (var item in unzipTasks)
            {
                var dicList = Directory.GetDirectories(item.DestDirPath, MsTaskService.DefaultHotMapDir, SearchOption.AllDirectories);
                if (dicList == null || dicList.Count() == 0)
                    continue;

                foreach (var dic in dicList)
                {
                    try
                    {
                        var destDir = dic.Replace(MsTaskService.DefaultHotMapDir, MsTaskService.ShareHotMapDir);
                        DirectoryCopy(dic, destDir);

                        copyDirList.Add((destDir, dic));

                        var tempMsPic = Directory.GetDirectories(destDir, "MsPic", SearchOption.AllDirectories);
                        if (tempMsPic == null || tempMsPic.Count() == 0)
                            continue;

                        msPicDicList.AddRange(tempMsPic);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex.Message, ex);
                    }
                }
            }

            //重新绘图
            foreach (var item in msPicDicList)
            {
                try
                {
                    //热力图绘图
                    var hotmapList = Directory.GetFiles(item, "*hotmap*");
                    foreach (var hot in hotmapList)
                    {
                        _ = MeasureDrawHotMapService.MeasureDrawHotMap_R(hot, 2.0f, Convert.ToInt32(AreaEnum.中));
                    }

                    //靠尺图绘图
                    var rulerList = Directory.GetFiles(item, "*ruler*");
                    bool has_flatness = true;
                    bool has_vertical = true;
                    foreach (var ruler in rulerList)
                    {
                        _ = MeasureDrawHotMapService.MeasureDrawRulers_R(ruler, true, true, ref has_flatness, ref has_vertical);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex.Message, ex);
                }
            }

            //此步骤为了解决算法的缺陷：Surface端上传的靠尺图可能没有标尺数据，而热力图分享数据的靠尺图由于调用过靠尺图重新生成算法，所以对应的靠尺图存在标尺数据
            foreach (var item in copyDirList)
            {
                DirectoryCopy(item.sourceDir, item.destDir);
            }
        }

        /// <summary>
        /// 复制文件夹（先删除后复制）
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="destDir"></param>
        private static void DirectoryCopy(string dic, string destDir)
        {
            try
            {
                if (Directory.Exists(destDir))
                    Directory.Delete(destDir, true);
                FileInfoUtil.DirectoryCopy(dic, destDir, true);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message, ex);
            }
        }
    }
}